<?php

class Utils {

    static function getUrl($url) {
        $firstStr = substr($url, 0, 1);
        $baseUrl = $firstStr == '/' ? baseUrl : baseUrl . '/';
        return $baseUrl . $url;
    }

    static function getPath($path) {
        if (is_string($path)) {
            $firstStr = substr($path, 0, 1);
            $basePath = $firstStr == DIRECTORY_SEPARATOR ? basePath : basePath . DIRECTORY_SEPARATOR;
            return $basePath . $path;
        } else if (is_array($path)) {
            $finalPath = basePath;
            foreach ($path as $pathStr) {
                $finalPath .= DIRECTORY_SEPARATOR . $pathStr;
            }
            return $finalPath;
        }
    }

    static function goToErrorPage($statusHTTP = StatusCodes::HTTP_NOT_FOUND, $newLocation = null) {
        ob_end_clean();
        session_write_close();

        $reeferLocation = getenv("HTTP_REFERER");
        if (!isset($reeferLocation) || !$reeferLocation)
            $reeferLocation = self::getUrl('');
        $newLocation = ($newLocation == null) ? $reeferLocation : $newLocation;

        $errorPageTitle = 'Error: ' . StatusCodes::getMessageForCode($statusHTTP);
        switch ($statusHTTP) {
            case StatusCodes::HTTP_NOT_FOUND:
                $errorMessage = 'The page you are trying to visit does not exist.';
                break;
            case StatusCodes::HTTP_FORBIDDEN:
                $errorMessage = 'You do not have permission to see this page.';
                break;
            case StatusCodes::HTTP_BAD_REQUEST:
                $errorMessage = 'The URL isn\'t valid.';
                break;
            default:
                $errorMessage = 'There is no additional information for this error.';
                break;
        }

        header(StatusCodes::httpHeaderFor($statusHTTP));
        include(self::getPath(array('error.php')));
    }

    static function splitString($string, $count) {
        if (strlen($string) > $count)
            return substr($string, 0, $count) . '...';
        else
            return $string;
    }
    
    static function cleanDoubleSpaces($str)
    {
        $clean = "";
        $parts = array();

        // divido la cadena con todos los espacios q haya
        $parts = split(" ", $str);

        foreach ($parts as $substr) {
            // de cada subcadena elimino sus espacios a los lados
            $substr = trim($substr);

            // luego lo vuelvo a unir con un espacio para formar la nueva cadena limpia
            // omitir los que sean unicamente espacios en blanco
            if ($substr != "") {
                $clean .= $substr . " ";
            }
        }
        $clean = trim($clean);

        return $clean;
    }  

    static function getFormatTime($strtime) {
        $now = time();
        $time = strtotime($strtime);
        $seconds = $now - $time;
        $days = floor($seconds / 86400);
        $mod_hours = $seconds % 86400;
        $hours = floor($mod_hours / 3600);
        $mod_minutes = $mod_hours % 3600;
        $minutes = floor($mod_minutes / 60);



        if ($days <= 0) {
            return date("H:i", $time);
        } else {
            return date("j M", $time);
        }
    }

    static function ago($strtime) {
        $diff = time() - strtotime($strtime);
        if ($diff >= 0) {
            $period = array("second", "minute", "hour", "day", "week", "month", "year");
            $length = array("60", "60", "24", "7", "4.35", "12");

            for ($j = 0; $j < 6 && $diff >= $length[$j]; $j++)
                $diff /= $length[$j];

            $diff = round($diff);

            if ($diff > 1)
                $period[$j].= "s";

            return $diff . " " . $period[$j] . ' ago';
        }else {
            return 'Date not valid';
        }
    }

    static function pagination($page, $pageMax, $url, $urlParam = null) {
        ?>
        <div id="pages" class="pages">
            <?php
            if ($pageMax > 1) {
                if ($urlParam == null) {
                    $urlParam = '';
                    foreach ($_GET as $key => $value) {
                        if ($key != 'page')
                            $urlParam .= htmlentities("&$key=$value");
                    }
                    substr($urlParam, 1);
                }

                $pageEnd = min($pageMax, 5);
                $pageActual = max($page - 2, 1);
                if ($page > 0) {
                    ?>
                    <a href="<?php echo $url . '?page=' . $page . $urlParam ?>" >previous</a> 
                    <?php
                    if ($page > 2 && $pageMax > 5) {
                        ?>
                        <a href="<?php echo $url . '?page=1' . $urlParam; ?>" >1</a> ... 
                        <?php
                        $pageActual = $page - 1;
                        $pageEnd = $page + 3;
                    }
                }else
                    echo ' previous ';

                if ($page + 3 > $pageMax) {
                    $pageActual = max($pageMax - 4, 1);
                    $pageEnd = min($page + 2, $pageMax);
                }

                for ($pageActual; $pageActual <= $pageEnd; $pageActual++) {
                    if ($pageActual == ($page + 1))
                        echo $pageActual;
                    else {
                        ?>
                        <a href="<?php echo $url . '?page=' . $pageActual . $urlParam ?>" ><?php echo $pageActual ?></a> 
                        <?php
                    }
                }
                if ($page + 3 < $pageMax && $pageMax > 5) {
                    ?>
                    ... <a href="<?php echo $url . '?page=' . $pageMax . $urlParam; ?>" ><?php echo $pageMax; ?></a> 
                    <?php
                }
                ?>
                <?php
                if ($page < $pageMax - 1) {
                    ?>
                    <a href="<?php echo $url . '?page=' . ($page + 2) . $urlParam ?>" >next</a>
                    <?php
                }else
                    echo ' next ';
            }
            ?>
        </div>
        <?php
    }

    //IMAGES
    static function imagecreatefrombmp($p_sFile) {
        //    Load the image into a string
        $file = fopen($p_sFile, "rb");
        $read = fread($file, 10);
        while (!feof($file) && ($read <> ""))
            $read .= fread($file, 1024);

        $temp = unpack("H*", $read);
        $hex = $temp[1];
        $header = substr($hex, 0, 108);

        if (substr($header, 0, 4) == "424d") {
            //    Cut it in parts of 2 bytes
            $header_parts = str_split($header, 2);

            //    Get the width        4 bytes
            $width = hexdec($header_parts[19] . $header_parts[18]);

            //    Get the height        4 bytes
            $height = hexdec($header_parts[23] . $header_parts[22]);

            //    Unset the header params
            unset($header_parts);
        }

        //    Define starting X and Y
        $x = 0;
        $y = 1;

        //    Create newimage
        $image = imagecreatetruecolor($width, $height);

        //    Grab the body from the image
        $body = substr($hex, 108);

        //    Calculate if padding at the end-line is needed
        //    Divided by two to keep overview.
        //    1 byte = 2 HEX-chars
        $body_size = (strlen($body) / 2);
        $header_size = ($width * $height);

        //    Use end-line padding? Only when needed
        $usePadding = ($body_size > ($header_size * 3) + 4);

        //    Using a for-loop with index-calculation instaid of str_split to avoid large memory consumption
        //    Calculate the next DWORD-position in the body
        for ($i = 0; $i < $body_size; $i+=3) {
            //    Calculate line-ending and padding
            if ($x >= $width) {
                //    If padding needed, ignore image-padding
                //    Shift i to the ending of the current 32-bit-block
                if ($usePadding)
                    $i += $width % 4;

                //    Reset horizontal position
                $x = 0;

                //    Raise the height-position (bottom-up)
                $y++;

                //    Reached the image-height? Break the for-loop
                if ($y > $height)
                    break;
            }

            //    Calculation of the RGB-pixel (defined as BGR in image-data)
            //    Define $i_pos as absolute position in the body
            $i_pos = $i * 2;
            $r = hexdec($body[$i_pos + 4] . $body[$i_pos + 5]);
            $g = hexdec($body[$i_pos + 2] . $body[$i_pos + 3]);
            $b = hexdec($body[$i_pos] . $body[$i_pos + 1]);

            //    Calculate and draw the pixel
            $color = imagecolorallocate($image, $r, $g, $b);
            imagesetpixel($image, $x, $height - $y, $color);

            //    Raise the horizontal position
            $x++;
        }

        //    Unset the body / free the memory
        unset($body);

        //    Return image-object
        return $image;
    }

    static function resizeImage($src, $size) {
        $image_info = getimagesize($src);
        if (!$image_info)
        {
            unlink($src);
            return "The image is corrupted, please try again with other file.";
        }
        $width = $image_info[0];
        $height = $image_info[1];

        $old_image = null;
        switch ($image_info[2]) {
            case IMAGETYPE_JPEG : $old_image = imagecreatefromjpeg($src);
                break;
            case IMAGETYPE_GIF : $old_image = imagecreatefromgif($src);
                break;
            case IMAGETYPE_PNG : $old_image = imagecreatefrompng($src);
                break;
            case IMAGETYPE_BMP :
                include_once($_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . 'abd' . DIRECTORY_SEPARATOR . 'utils.php');
                $old_image = Utils::imagecreatefrombmp($src);
                break;
        }
        $type_file = strrchr($src, '.');
        $newSrc = str_ireplace($type_file, '.png', $src);

        if ($width > $size || $height > $size) {
            if ($width > $height) { //ResizeToWidth
                $ratio = $size / $width;
                $height = $height * $ratio;
                $width = $size;
            } else {//ResizeToHeight
                $ratio = $size / $height;
                $width = $width * $ratio;
                $height = $size;
            }
        } else {
            $width = $image_info[0];
            $height = $image_info[1];
        }

        $new_image = imagecreatetruecolor($width, $height);
        imagesavealpha($new_image, true);
        $trans_colour = imagecolorallocatealpha($new_image, 0, 0, 0, 127);
        imagefill($new_image, 0, 0, $trans_colour);
        imagecopyresampled($new_image, $old_image, 0, 0, 0, 0, $width, $height, $image_info[0], $image_info[1]);

        unlink($src);
        imagepng($new_image, $newSrc);
        imagedestroy($old_image);
        imagedestroy($new_image);
    }

//FILES
    static function delete_files($src, $time = null, $removeBase = false) {
        if (is_dir($src)) {
            $dh = opendir($src);
            if ($dh) {
                while (($file = readdir($dh))) {
                    $permiss = $file[0] != '.';
                    if ($permiss && (!isset($time) || time() - filemtime($src . DIRECTORY_SEPARATOR . $file) > strtotime($time) - strtotime('00:00:00')))
                        unlink($src . DIRECTORY_SEPARATOR . $file);
                }
                closedir($dh);
            }
        }
        if ($removeBase)
            rmdir($src);
    }

    static function showError($message) {
        $_SESSION['errorMessage'] = htmlspecialchars($message, ENT_QUOTES);
    }

    static function showErrorList($list) {
        $errors = "";

        foreach ($list as $error) {
            $errors .= "<li>" . htmlspecialchars($error, ENT_QUOTES) . "</li>";
        }
        $_SESSION['errorMessage'] = '<span class="error-count">' . count($list) . '</span> errors were detected:<ul>' . $errors . '</ul>';
    }

    static function showInfo($message) {
        $_SESSION['infoMessage'] = $message;
    }

}

class StatusCodes {
    // [Informational 1xx]
    const HTTP_CONTINUE = 100;
    const HTTP_SWITCHING_PROTOCOLS = 101;
    // [Successful 2xx]
    const HTTP_OK = 200;
    const HTTP_CREATED = 201;
    const HTTP_ACCEPTED = 202;
    const HTTP_NONAUTHORITATIVE_INFORMATION = 203;
    const HTTP_NO_CONTENT = 204;
    const HTTP_RESET_CONTENT = 205;
    const HTTP_PARTIAL_CONTENT = 206;
    // [Redirection 3xx]
    const HTTP_MULTIPLE_CHOICES = 300;
    const HTTP_MOVED_PERMANENTLY = 301;
    const HTTP_FOUND = 302;
    const HTTP_SEE_OTHER = 303;
    const HTTP_NOT_MODIFIED = 304;
    const HTTP_USE_PROXY = 305;
    const HTTP_UNUSED= 306;
    const HTTP_TEMPORARY_REDIRECT = 307;
    // [Client Error 4xx]
    const errorCodesBeginAt = 400;
    const HTTP_BAD_REQUEST = 400;
    const HTTP_UNAUTHORIZED = 401;
    const HTTP_PAYMENT_REQUIRED = 402;
    const HTTP_FORBIDDEN = 403;
    const HTTP_NOT_FOUND = 404;
    const HTTP_METHOD_NOT_ALLOWED = 405;
    const HTTP_NOT_ACCEPTABLE = 406;
    const HTTP_PROXY_AUTHENTICATION_REQUIRED = 407;
    const HTTP_REQUEST_TIMEOUT = 408;
    const HTTP_CONFLICT = 409;
    const HTTP_GONE = 410;
    const HTTP_LENGTH_REQUIRED = 411;
    const HTTP_PRECONDITION_FAILED = 412;
    const HTTP_REQUEST_ENTITY_TOO_LARGE = 413;
    const HTTP_REQUEST_URI_TOO_LONG = 414;
    const HTTP_UNSUPPORTED_MEDIA_TYPE = 415;
    const HTTP_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
    const HTTP_EXPECTATION_FAILED = 417;
    // [Server Error 5xx]
    const HTTP_INTERNAL_SERVER_ERROR = 500;
    const HTTP_NOT_IMPLEMENTED = 501;
    const HTTP_BAD_GATEWAY = 502;
    const HTTP_SERVICE_UNAVAILABLE = 503;
    const HTTP_GATEWAY_TIMEOUT = 504;
    const HTTP_VERSION_NOT_SUPPORTED = 505;

    private static $messages = array(
        // [Informational 1xx]
        100 => '100 Continue',
        101 => '101 Switching Protocols',
        // [Successful 2xx]
        200 => '200 OK',
        201 => '201 Created',
        202 => '202 Accepted',
        203 => '203 Non-Authoritative Information',
        204 => '204 No Content',
        205 => '205 Reset Content',
        206 => '206 Partial Content',
        // [Redirection 3xx]
        300 => '300 Multiple Choices',
        301 => '301 Moved Permanently',
        302 => '302 Found',
        303 => '303 See Other',
        304 => '304 Not Modified',
        305 => '305 Use Proxy',
        306 => '306 (Unused)',
        307 => '307 Temporary Redirect',
        // [Client Error 4xx]
        400 => '400 Bad Request',
        401 => '401 Unauthorized',
        402 => '402 Payment Required',
        403 => '403 Forbidden',
        404 => '404 Not Found',
        405 => '405 Method Not Allowed',
        406 => '406 Not Acceptable',
        407 => '407 Proxy Authentication Required',
        408 => '408 Request Timeout',
        409 => '409 Conflict',
        410 => '410 Gone',
        411 => '411 Length Required',
        412 => '412 Precondition Failed',
        413 => '413 Request Entity Too Large',
        414 => '414 Request-URI Too Long',
        415 => '415 Unsupported Media Type',
        416 => '416 Requested Range Not Satisfiable',
        417 => '417 Expectation Failed',
        // [Server Error 5xx]
        500 => '500 Internal Server Error',
        501 => '501 Not Implemented',
        502 => '502 Bad Gateway',
        503 => '503 Service Unavailable',
        504 => '504 Gateway Timeout',
        505 => '505 HTTP Version Not Supported'
    );

    public static function httpHeaderFor($code) {
        return 'HTTP/1.1 ' . self::$messages[$code];
    }

    public static function getMessageForCode($code) {
        return self::$messages[$code];
    }

    public static function isError($code) {
        return is_numeric($code) && $code >= self::HTTP_BAD_REQUEST;
    }

    public static function canHaveBody($code) {
        return
                // True if not in 100s
                ($code < self::HTTP_CONTINUE || $code >= self::HTTP_OK)
                && // and not 204 NO CONTENT
                $code != self::HTTP_NO_CONTENT
                && // and not 304 NOT MODIFIED
                $code != self::HTTP_NOT_MODIFIED;
    }

}
?>